package com.com.unionpay.speech.util;

import com.github.stuxuhai.jpinyin.ChineseHelper;
import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinFormat;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.sdk.LogUtils;

import java.util.HashMap;
import java.util.Stack;
import java.util.regex.Pattern;

public class Money2Digit {


    private static final HashMap<String, Integer> numbers;

    static {
        numbers = new HashMap<>();
        numbers.put("一", 1);
        numbers.put("1", 1);
        numbers.put("yi", 1);

        numbers.put("两", 2);
        numbers.put("二", 2);
        numbers.put("2", 2);
        numbers.put("貳", 2);
        numbers.put("er", 2);
        numbers.put("liang", 2);


        numbers.put("三", 3);
        numbers.put("3", 3);
        numbers.put("san", 3);

        numbers.put("四", 4);
        numbers.put("si", 4);
        numbers.put("4", 4);

        numbers.put("五", 5);
        numbers.put("5", 5);
        numbers.put("伍", 5);
        numbers.put("wu", 5);


        numbers.put("六", 6);
        numbers.put("6", 6);
        numbers.put("liu",6);

        numbers.put("七", 7);
        numbers.put("7", 7);
        numbers.put("qi", 7);


        numbers.put("八", 8);
        numbers.put("8", 8);
        numbers.put("ba", 8);


        numbers.put("九", 9);
        numbers.put("9", 9);
        numbers.put("jiu", 9);

        //numbers.put('十', 10);
        numbers.put("零", 0);
        numbers.put("0", 0);
        numbers.put("ling", 0);
    }


    private static final HashMap<String, Integer> units = new HashMap<>();

    static {
        units.put("億", 100000000);
        units.put("亿", 100000000);

        units.put("万", 10000);
        units.put("萬", 10000);
        units.put("wan", 10000);
        units.put("one", 10000);

        units.put("仟", 1000);
        units.put("千", 1000);
        units.put("qian", 1000);

        units.put("佰", 100);
        units.put("百", 100);
        units.put("bai", 100);
        units.put("十", 10);
        units.put("shi", 10);

    }

    public static long int2num(String cnString) {
        long num = 0;

        cnString = cnString.replace("hui", "kuai");
        // String aval = "零一二三四五六七八九";
        // String bval = "十百千万亿";
        // 这个个标识位，用来判断当前数字 只有1-9
        boolean isSimple = true;
      LogUtils.i("cnString=" + cnString);
        String[] arr = cnString.split(cnString.contains(",") ? "," : "");
        Stack<Integer> stack = new Stack<>();
        String temp = "";

        for (String currentChar : arr) {
            //跳过零
            temp = String.valueOf(currentChar);
//            if (numbers.containsKey(currentChar) && numbers.get(currentChar) == 0) continue;
          LogUtils.i("currentChar=" + currentChar);
            //如果不在bval中，即当前字符为数字，直接入栈
            if (units.containsKey(currentChar)) { //当前字符为单位。
                isSimple = false;
              LogUtils.i("bai=" + currentChar);
                int tempsum = 0;
                // 当前单位对应数字
                int val = units.get(currentChar);
                //如果栈为空则直接入栈
                if (stack.isEmpty()) {
                    stack.push(val);
                    continue;
                }
                //如果栈中有比val小的元素则出栈，累加，乘N，再入栈
                while (!stack.isEmpty() && stack.peek() < val) {
                    tempsum += stack.pop();
                }
                //判断是否经过乘法处理
                if (tempsum == 0) {
                    stack.push(val);
                } else {
                    stack.push(tempsum * val);
                }
            } else if (numbers.containsKey(currentChar)) {//当前字符为数字。
              LogUtils.i("shi=" + currentChar);
                if (isSimple && !stack.empty()) {
                    stack.push(stack.pop() * 10 + numbers.get(currentChar));
                } else {
                    stack.push(numbers.get(currentChar));
                }
                isSimple = true;
            } else {
                isSimple = false;
            }
        }
        //计算最终的和
        while (!stack.isEmpty()) {
            num += stack.pop();
        }
        System.out.println(num);
      LogUtils.i("num=" + num);
        return num;

    }

    /**
     * 方法中涵盖了日常结账中多种口语化说法，
     *
     * @param chiNumber
     * @return
     */
    public static double float2numstring(String chiNumber) {

      LogUtils.i("float2numstring=" + chiNumber);
        int num = 0;
        int lastVal = 0;
        int jiaoVal = 0;
        int fenVal = 0;
        String[] money = null;
        if (chiNumber.contains(",")) {
            if (chiNumber.startsWith(","))
            chiNumber = chiNumber.substring(1, chiNumber.length()).trim();
            money = chiNumber.split(",");
        } else {
            money = chiNumber.split("");
        }
        if (chiNumber.contains("kuai") || chiNumber.contains("yuan")) {
            //覆盖1.32
            if (numbers.containsKey(money[0])) num = numbers.get(money[0]) * 10;
            if (numbers.containsKey(money[1])) num += numbers.get(money[1]);
            return (double) num / 100;
        }

      LogUtils.i("float2numstring=" + money.length);
        for (int i = 0; i < money.length; i++) {
            String currentChar = money[i];
            if (numbers.containsKey(currentChar)) {//当前字符为数字。
                lastVal = lastVal * 10 + numbers.get(currentChar);
                if (i == money.length - 1 && jiaoVal != 0) {
                    //适应三块九毛八
                    fenVal = lastVal;
                    lastVal = 0;
                }
                if (money.length == 1 && jiaoVal == 0 && fenVal == 0) {
                    //  适应一块三
                    jiaoVal = lastVal;
                    lastVal = 0;
                }
            } else if (currentChar.contains("jiao") || currentChar.contains("mao")) {
                jiaoVal = lastVal;
                lastVal = 0;
            } else if (currentChar.contains("fen") || jiaoVal != 0) {
                fenVal = lastVal;
                lastVal = 0;
            }
        }

        if (jiaoVal != 0 || fenVal != 0) { // 存在角或者分
            num = jiaoVal * 10 + fenVal;
        } else {
            num = lastVal;
        }
      LogUtils.i("num=" + num);
        return (double) num / 100;
    }

    public static String postiveChinese2number(String chiNumber) {

      LogUtils.i("chiNumber=" + chiNumber);
        String[] kuaiArr = {"点", ".", "块", "元", "快", "dian", "kuai", "yuan"};
        for (String key : kuaiArr) {
            if (chiNumber.contains(key)) {
                String[] numberArray = chiNumber.split(key);
                String integerPart = numberArray[0];
                if (numberArray.length == 2) {

                    String floatPart = chiNumber.split(key)[1];
                    return (int2num(integerPart) + float2numstring(floatPart)) + "";
                } else
                    return int2num(integerPart) + "";
            }
        }
        return int2num(chiNumber) + "";

    }

    /**
     * 方法内如果传入的是1.32元，Stirng#split 方法返回的数组length 为0
     * 暂未发现具体原因
     * <p>
     * 目前方法是将 . 替换成 dian
     * <p>
     * <p>
     * 百度语音返回的值  有时候会把 块 识别为 会
     *
     * @param chiNumber
     * @return
     */
    public static String convertToPinyin2Num(String chiNumber) {
        String[] moneyUnit = {"点", ".", "dian", "块", "元", "快", "kuai", "yuan", "hui"};
        if (ChineseHelper.containsChinese(chiNumber)) {
            try {
                String money = PinyinHelper.convertToPinyinString(chiNumber, ",", PinyinFormat.WITHOUT_TONE);
                if (money.contains("."))
                    money = money.replace(".", "dian");
              LogUtils.i("文字转拼音=" + money);
                for (String key : moneyUnit) {
                    if (money.contains(key)) {
                        String[] numberArray = money.split(key);
                        String integerPart = numberArray[0];
                      LogUtils.i("integerpa=" + key + "/" + numberArray.length);
                        if (numberArray.length == 2) {
                            String floatPart = numberArray[1];
                            return formatDigit(int2num(integerPart) + float2numstring(floatPart) + "");
                        } else {
                            return formatDigit(int2num(integerPart) + "");
                        }
                    }
                }
                //针对低于一元的情况
                if (money.contains("mao") || money.contains("fen") || money.contains("jiao"))
                    return formatDigit(String.valueOf(float2numstring(money)));

                return formatDigit(int2num(money) + "");
            } catch (PinyinException e) {
                e.printStackTrace();
            }
            return "";
        } else {
            return formatDigit(chiNumber);
        }
    }

    /**
     * 对转化出来的字符串做校验
     * @param str
     * @return
     */
    public static String formatDigit(String str) {
        boolean pattern = Pattern.matches("^\\d+(\\.\\d+)?$", str);
        return pattern ? str : "";
    }

    public static void main(String[] args) {
        Money2Digit money2Digit = new Money2Digit();

        String mm = money2Digit.postiveChinese2number("貳佰五十元三七");
         mm = money2Digit.postiveChinese2number("三块五");

        System.out.println(mm);
    }

}
